package com.caiyi.tips.core.web;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.caiyi.tips.core.web.constant.RequestAttributeConst;
import com.google.common.collect.ImmutableMap;
import lombok.Getter;
import lombok.Setter;

import javax.servlet.http.HttpServletRequest;
import java.time.OffsetDateTime;
import java.util.Enumeration;
import java.util.Map;

@Getter
@Setter
public class RequestDetailsLogger {


    @JSONField(serialize = false)
    private final HttpServletRequest request;

    private String requestId;

    private String url;

    private String method;

    private ImmutableMap<String, Object> paramsMap;

    private ImmutableMap<String, Object> headers;

    private String apiDesc;

    private String requestBody;

    private OffsetDateTime requestTime = OffsetDateTime.now();

    private OffsetDateTime responseTime;

    private String characterEncoding;

    private long contentLength;

    private String remoteHost;

    private int remotePort;

    public RequestDetailsLogger() {

        request = ServletContextHolder.getRequest();
        requestId = ServletContextHolder.fetchRequestId();
        url = request.getRequestURL().toString();
        method = request.getMethod();
        paramsMap = fetParamsMap(request);
        headers = fetchHttpHeaders(request);
        requestBody = (String) request.getAttribute(RequestAttributeConst.REQUEST_BODY_KEY);
        characterEncoding = request.getCharacterEncoding();
        contentLength = request.getContentLengthLong();
        remoteHost = request.getRemoteHost();
        remotePort = request.getRemotePort();
    }

    private ImmutableMap<String, Object> fetParamsMap(HttpServletRequest request) {
        final Map<String, String[]> parameterMap = request.getParameterMap();
        final ImmutableMap.Builder<String, Object> singleValueParams = ImmutableMap.builder();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            singleValueParams.put(entry.getKey(), entry.getValue()[0]);
        }
        return singleValueParams.build();
    }

    private ImmutableMap<String, Object> fetchHttpHeaders(HttpServletRequest request) {
        final ImmutableMap.Builder<String, Object> headerBuilder = ImmutableMap.builder();
        final Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            final String headerName = headerNames.nextElement();
            headerBuilder.put(headerName, request.getHeader(headerName));
        }
        return headerBuilder.build();
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }
}
